#include <iostream>
#include <string>
#include <pthread.h>
//#include <thread>
#include <unistd.h>
#include <vector>
#include <cstdlib>
#include "LockGuard.hpp"
#include "Thread.hpp"

class ThreadData
{
public:
    ThreadData(int& ticket, const string& name, pthread_mutex_t& mutex)//ticket构造少了个引用！！！
        :_ticket(ticket), _name(name), _mutex(mutex), _total(0)
    {}
    ~ThreadData()
    {}

    int& _ticket;
    string _name;
    int _total;
    pthread_mutex_t& _mutex;
};

//pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;//全局加锁

//抢票系统
int g_ticket = 10000;//票数

// void route(ThreadData* td)
// {
//     while(true)
//     {
//         pthread_mutex_lock(&td->_mutex);//加锁
//         if(td->_ticket> 0)
//         {
//             usleep(1000);
//             cout<< "run thread is: " << td->_name << " ticket: " << td->_ticket <<endl;
//             td->_ticket--;
//             pthread_mutex_unlock(&td->_mutex);//解锁
//             td->_total++;
//         }
//         else 
//         {
//             pthread_mutex_unlock(&td->_mutex);//解锁
//             break; 
//         }
//     }
// }

void route(ThreadData* td)
{
    while(true)
    {
        LockGuard guard(&td->_mutex);//临时对象，刚创建即构造加锁，出作用域析构解锁
        if(td->_ticket> 0)
        {
            usleep(1000);
            cout<< "run thread is: " << td->_name << " ticket: " << td->_ticket <<endl;
            td->_ticket--;
            td->_total++;
        }
        else 
        {
            break; 
        }
    }
}
const int num = 4;
int main()
{
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, nullptr);//初始化锁

    vector<yss::Thread<ThreadData*>> threads;
    vector<ThreadData*> datas;

    // 创建一批线程
    for(int i=0; i<num; i++)
    {
        string name = "thread-" + to_string(i+1);
        ThreadData* td = new ThreadData(g_ticket, name, mutex);
        threads.emplace_back(route, td, name);
        datas.emplace_back(td);
    }
    // 启动一批线程
    for(auto& thread:threads)
    {
        thread.Start();
    }
    // 等待一批线程
    for(auto& thread:threads)
    {
        thread.Join();
        cout << "wait thread done... , threadname is: " << thread.getName() << endl;
    }
    // 统计数据
    for(auto data:datas)
    {
        cout<<"thread name: " << data->_name << " total: " << data->_total <<endl;
        delete data;
    }
    pthread_mutex_destroy(&mutex);//销毁锁
    return 0;
}